package com.okex.demo.service;

import com.okex.demo.model.Account;
import com.okex.demo.repository.AccountRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Optional;

@Service
public class AccountService {

    private static final Logger log = LoggerFactory.getLogger(AccountService.class);

    @Autowired
    private AccountRepository accountRepository;
    
    @PersistenceContext
    private EntityManager entityManager;
    
    /**
     * 查找所有账户
     */
    public List<Account> findAll() {
        return accountRepository.findAll();
    }
    
    /**
     * 查找所有有效账户（产品ID不为空的）
     */
    public List<Account> findAllActive() {
        return accountRepository.findAllWithInstId();
    }
    
    /**
     * 查找所有有产品ID的账户
     */
    public List<Account> findAllWithInstId() {
        return accountRepository.findAllWithInstId();
    }
    
    /**
     * 根据ID查找账户
     */
    public Optional<Account> findById(Long id) {
        return accountRepository.findById(id);
    }
    
    /**
     * 根据产品ID查找账户
     */
    public Optional<Account> findByInstId(String instId) {
        return accountRepository.findByInstId(instId);
    }
    
    /**
     * 根据产品ID查找账户（先精确匹配，然后基础名称匹配）
     */
    public Optional<Account> findByInstIdWithFlexibleMatching(String instId) {
        log.info("开始灵活匹配产品ID: {}", instId);
        
        // 1. 先尝试精确匹配
        Optional<Account> directMatch = accountRepository.findByInstId(instId);
        if (directMatch.isPresent()) {
            log.info("找到精确匹配: {}", directMatch.get().getAccountName());
            return directMatch;
        }
        log.info("未找到精确匹配, 尝试基础部分匹配");
        
        // 2. 尝试通过基础部分匹配
        String basePart = null;
        if (instId != null && instId.contains("-")) {
            basePart = instId.substring(0, instId.indexOf("-"));
        } else if (instId != null) {
            basePart = instId;
        }
        
        if (basePart != null) {
            log.info("尝试基础部分匹配: {}", basePart);
            List<Account> baseMatches = accountRepository.findByInstIdBasePartStartingWith(basePart);
            if (!baseMatches.isEmpty()) {
                log.info("找到基础部分匹配: {}", baseMatches.get(0).getAccountName());
                return Optional.of(baseMatches.get(0));
            }
        }
        log.info("未找到基础部分匹配, 尝试模糊匹配");
        
        // 3. 尝试模糊匹配
        if (instId != null) {
            List<Account> fuzzyMatches = accountRepository.findByInstIdContaining(instId);
            if (!fuzzyMatches.isEmpty()) {
                log.info("找到模糊匹配: {}", fuzzyMatches.get(0).getAccountName());
                return Optional.of(fuzzyMatches.get(0));
            }
        }
        
        log.warn("未找到任何匹配: {}", instId);
        return Optional.empty();
    }
    
    /**
     * 根据账户名称查找账户
     */
    public Optional<Account> findByAccountName(String accountName) {
        return accountRepository.findByAccountName(accountName);
    }
    
    /**
     * 保存或更新账户（基础方法）
     */
    @Transactional
    public Account save(Account accountEntity) {
        return accountRepository.save(accountEntity);
    }
    
    /**
     * 保存或更新账户，保留创建时间和其他内部状态字段
     */
    @Transactional
    public Account saveWithFieldPreservation(Account accountToSave) {
        log.info("保存账户 ID={}, 名称={}, instId={}", accountToSave.getId(), accountToSave.getAccountName(), accountToSave.getInstId());
        
        try {
            // 如果是更新操作（ID不为空）
            if (accountToSave.getId() != null) {
                // 先从数据库获取最新的实体
                Optional<Account> existingOpt = accountRepository.findById(accountToSave.getId());
                if (existingOpt.isPresent()) {
                    Account existingAccount = existingOpt.get();
                    log.info("找到现有账户: ID={}, 名称={}, 版本={}", existingAccount.getId(), existingAccount.getAccountName(), existingAccount.getVersion());
                    
                    // 检查instId是否与其他账户冲突
                    if (accountToSave.getInstId() != null && !accountToSave.getInstId().equals(existingAccount.getInstId())) {
                        Optional<Account> conflictAccount = accountRepository.findByInstId(accountToSave.getInstId());
                        if (conflictAccount.isPresent() && !conflictAccount.get().getId().equals(accountToSave.getId())) {
                            log.error("保存失败：instId {} 已被其他产品使用", accountToSave.getInstId());
                            throw new RuntimeException("产品ID已被其他产品使用，请使用其他产品ID");
                        }
                    }
                    
                    // 将表单提交的值复制到现有实体，保留版本号和创建时间
                    copyNonNullProperties(accountToSave, existingAccount);
                    
                    // 设置更新时间
                    existingAccount.setUpdatedAt(new Date());
                    
                    // 使用repository保存更新后的实体
                    log.info("保存更新后的账户: ID={}, 版本={}", existingAccount.getId(), existingAccount.getVersion());
                    return accountRepository.save(existingAccount);
                } else {
                    log.warn("未找到ID={}的账户", accountToSave.getId());
                }
            }
            
            // 如果是新增操作（ID为空）
            else {
                // 检查是否已存在相同instId的账户
                if (accountToSave.getInstId() != null) {
                    Optional<Account> existingWithSameInstId = accountRepository.findByInstId(accountToSave.getInstId());
                    if (existingWithSameInstId.isPresent()) {
                        log.error("保存失败：instId {} 已存在", accountToSave.getInstId());
                        throw new RuntimeException("产品ID已存在，请使用其他产品ID");
                    }
                }
                
                // 设置创建时间和更新时间
                if (accountToSave.getCreatedAt() == null) {
                    accountToSave.setCreatedAt(new Date());
                }
                accountToSave.setUpdatedAt(new Date());
                
                // 设置默认值
                setDefaultValues(accountToSave);
                
                // 使用repository保存新实体
                log.info("保存新账户: instId={}", accountToSave.getInstId());
                return accountRepository.save(accountToSave);
            }
            
            // 如果更新操作未找到现有实体，则作为新实体保存
            log.info("作为新实体保存: instId={}", accountToSave.getInstId());
            if (accountToSave.getCreatedAt() == null) {
                accountToSave.setCreatedAt(new Date());
            }
            accountToSave.setUpdatedAt(new Date());
            setDefaultValues(accountToSave);
            return accountRepository.save(accountToSave);
            
        } catch (Exception e) {
            log.error("保存产品失败: {}", e.getMessage(), e);
            throw new RuntimeException("保存产品失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 将非空属性从源对象复制到目标对象
     */
    private void copyNonNullProperties(Account source, Account target) {
        if (source.getInstId() != null) target.setInstId(source.getInstId());
        if (source.getAccountName() != null) target.setAccountName(source.getAccountName());
        if (source.getCrossPriceDiff() != null) target.setCrossPriceDiff(source.getCrossPriceDiff());
        if (source.getCrossTakeProfit() != null) target.setCrossTakeProfit(source.getCrossTakeProfit());
        if (source.getCrossMargin() != null) target.setCrossMargin(source.getCrossMargin());
        if (source.getCrossPriceDiffMargin() != null) target.setCrossPriceDiffMargin(source.getCrossPriceDiffMargin());
        if (source.getCrossLongReplenishCount() > 0) target.setCrossLongReplenishCount(source.getCrossLongReplenishCount());
        if (source.getCrossShortReplenishCount() > 0) target.setCrossShortReplenishCount(source.getCrossShortReplenishCount());
        if (source.getCrossLongCost() != null) target.setCrossLongCost(source.getCrossLongCost());
        if (source.getCrossShortCost() != null) target.setCrossShortCost(source.getCrossShortCost());
        if (source.getFaceValue() != null) target.setFaceValue(source.getFaceValue());
        if (source.getConversionPriceDiff() != null) target.setConversionPriceDiff(source.getConversionPriceDiff());
        if (source.getCrossToIsolatedShortPriceDiff() != null) target.setCrossToIsolatedShortPriceDiff(source.getCrossToIsolatedShortPriceDiff());
        if (source.getCrossToIsolatedLongCost() != null) target.setCrossToIsolatedLongCost(source.getCrossToIsolatedLongCost());
        if (source.getIsolatedPriceDiff() != null) target.setIsolatedPriceDiff(source.getIsolatedPriceDiff());
        if (source.getIsolatedMargin() != null) target.setIsolatedMargin(source.getIsolatedMargin());
        if (source.getIsolatedPriceDiffMargin() != null) target.setIsolatedPriceDiffMargin(source.getIsolatedPriceDiffMargin());
        if (source.getIsolatedLongReplenishCount() > 0) target.setIsolatedLongReplenishCount(source.getIsolatedLongReplenishCount());
        if (source.getIsolatedShortReplenishCount() > 0) target.setIsolatedShortReplenishCount(source.getIsolatedShortReplenishCount());
        if (source.getLeverage() != null) target.setLeverage(source.getLeverage());
        if (source.getIsTransferIsolatedShort() != null) target.setIsTransferIsolatedShort(source.getIsTransferIsolatedShort());
        if (source.getIsTransferIsolatedLong() != null) target.setIsTransferIsolatedLong(source.getIsTransferIsolatedLong());
        if (source.getIsolatedLongCost() != null) target.setIsolatedLongCost(source.getIsolatedLongCost());
        if (source.getIsolatedShortCost() != null) target.setIsolatedShortCost(source.getIsolatedShortCost());
    }
    
    /**
     * 设置默认值
     */
    private void setDefaultValues(Account account) {
        // 确保没有null值
        if (account.getCrossLongCost() == null) account.setCrossLongCost(BigDecimal.ZERO);
        if (account.getCrossShortCost() == null) account.setCrossShortCost(BigDecimal.ZERO);
        if (account.getCrossToIsolatedShortPriceDiff() == null) account.setCrossToIsolatedShortPriceDiff(BigDecimal.ZERO);
        if (account.getCrossToIsolatedLongCost() == null) account.setCrossToIsolatedLongCost(BigDecimal.ZERO);
        if (account.getIsolatedLongCost() == null) account.setIsolatedLongCost(BigDecimal.ZERO);
        if (account.getIsolatedShortCost() == null) account.setIsolatedShortCost(BigDecimal.ZERO);
        
        // 确保补仓次数不会为0
        if (account.getCrossLongReplenishCount() <= 0) account.setCrossLongReplenishCount(1);
        if (account.getCrossShortReplenishCount() <= 0) account.setCrossShortReplenishCount(1);
        if (account.getIsolatedLongReplenishCount() <= 0) account.setIsolatedLongReplenishCount(1);
        if (account.getIsolatedShortReplenishCount() <= 0) account.setIsolatedShortReplenishCount(1);
        
        // 确保布尔字段不会为null
        if (account.getIsTransferIsolatedShort() == null) account.setIsTransferIsolatedShort(true);
        if (account.getIsTransferIsolatedLong() == null) account.setIsTransferIsolatedLong(true);
    }
    
    /**
     * 删除账户
     */
    @Transactional
    public void delete(Long id) {
        accountRepository.deleteById(id);
    }
    
    /**
     * 初始化默认账户数据
     */
    @Transactional
    public void initDefaultAccounts() {
        // 如果没有账户数据，创建几个默认账户
        if (accountRepository.count() == 0) {
            createDefaultAccount("BTC-USD-SWAP", "比特币永续合约", "20", "50", "100");
            createDefaultAccount("ETH-USD-SWAP", "以太坊永续合约", "20", "50", "100");
            createDefaultAccount("LTC-USD-SWAP", "莱特币永续合约", "20", "50", "100");
            createDefaultAccount("XRP-USD-SWAP", "瑞波币永续合约", "20", "50", "100");
        }
    }
    
    /**
     * 创建默认账户
     */
    private Account createDefaultAccount(String instId, String accountName, String leverage, String margin, String priceGap) {
        Account newAccount = new Account();
        newAccount.setInstId(instId);                           // 产品ID
        newAccount.setAccountName(accountName);                 // 账户名称
        newAccount.setLeverage(leverage);                       // 杠杆倍数
        
        // 设置默认值
        newAccount.setCrossPriceDiff(new BigDecimal(priceGap));      // 全仓价差
        newAccount.setCrossTakeProfit(new BigDecimal("1000"));       // 全仓止盈
        newAccount.setCrossMargin(new BigDecimal(margin));           // 全仓保证金
        newAccount.setCrossPriceDiffMargin(new BigDecimal(margin));  // 全仓价差保证金
        newAccount.setCrossLongReplenishCount(1);                    // 全仓多仓补仓次数
        newAccount.setCrossShortReplenishCount(1);                   // 全仓空仓补仓次数
        newAccount.setFaceValue(new BigDecimal("0.001"));           // 面值
        newAccount.setConversionPriceDiff(new BigDecimal("100"));    // 转换价差
        newAccount.setIsolatedPriceDiff(new BigDecimal(priceGap));   // 逐仓价差
        newAccount.setIsolatedMargin(new BigDecimal(margin));        // 逐仓保证金
        newAccount.setIsolatedPriceDiffMargin(new BigDecimal(margin)); // 逐仓价差保证金
        newAccount.setIsolatedLongReplenishCount(1);                 // 逐仓多仓补仓次数
        newAccount.setIsolatedShortReplenishCount(1);                // 逐仓空仓补仓次数
        newAccount.setIsTransferIsolatedShort(true);                 // 是否转移逐仓空仓
        newAccount.setIsTransferIsolatedLong(true);                  // 是否转移逐仓多仓
        
        return accountRepository.save(newAccount);
    }
} 